home *** CD-ROM | disk | FTP | other *** search
- /*
- Test mappings
- */
-
- #include <QDOffscreen.h>
- #include <FixMath.h>
-
- #include "instructions.h"
-
- long Microseconds() = 0xA093;
-
- #define pictID 128
- #define kFrameCount 16 // 16 and 32 are kinda nice
-
-
- void
- MakeSineTable(short *theTable)
- {
-
- #define cycleSize (kFrameCount / 2)
- #define twoPiOverCycleSize (205887/cycleSize)
- #define amplitude 4
-
- short i;
-
- for (i = 0; i < 32; i++)
- *theTable++ = (amplitude * Frac2Fix(FracSin(i * twoPiOverCycleSize))+32768) >> 16;
-
- }
- void MapCoordinates(short width, short height, short x, short y,
- short *resultX, short *resultY,
- short frameNumber,
- short *theTable)
-
- {
- #define HorizontalSineWave 0
- #define VerticalSineWave 1
- #define Mirror 0
- #define Identity 0
-
-
- #if Identity
- *resultX = x;
- *resultY = y;
- #endif
-
- #if Mirror
- *resultX = width - x;
- *resultY = y;
- #endif
-
- #if HorizontalSineWave
- *resultX = x + (18 * Frac2Fix(FracSin(y * twoPiOverCycleSize))+32768) >> 16;
- *resultY = y;
- #endif
-
- #if VerticalSineWave
- *resultX = x;
- *resultY = y + theTable[(x + frameNumber) % 32];
- #endif
-
- while (*resultX < 0)
- *resultX += width;
- while (*resultY < 0)
- *resultY += height;
-
- *resultX %= width;
- *resultY %= height;
- }
-
- /*
- Generate the addresses for one 32-pixel column.
- */
-
- void
- GenerateMappingColumn( long *buffer1, short width, short height, short rowBytes,
- short frameNumber, short *theTable)
- {
- long *offsetHere;
- short x, y;
-
- offsetHere = buffer1;
-
- for (y = 0; y < height; ++y) {
- for (x = 0; x < 32; ++x)
- {
- short destinationX, destinationY;
-
- MapCoordinates(width, height, x, y, &destinationX, &destinationY,
- frameNumber, theTable);
- *offsetHere++ = (long)destinationY * rowBytes + destinationX;
- }
- }
- }
-
- void
- BlitOneColumn(char *sourceBase, char *destinationBase, short height,
- short rowBytes, long *columnMapping)
-
- {
- short x, y;
- char *sourceRow, *sourceByte;
- long *offsetHere;
-
- for (y = 0; y < height; ++y)
- {
- short byte;
-
- sourceByte = sourceBase;
- for (byte = 0; byte < 32; ++byte)
- *(destinationBase + *columnMapping++) = *sourceByte++;
- sourceBase += rowBytes;
- }
- }
-
-
- //
- // Blit the entire bitmap from source to dest using a technique similar to what
- // we'd like to compile.
- //
- // Use 5 destination registers so we can use 16-bit constant offsets in instructions
- // of the form:
- //
- // move.b (sourceRow)+, tableValue(destReg[0..4])
- //
- //
- #define EMIT_POSTINC 0
-
- void
- WriteSomeCode(short height, short rowBytes, long *mappingTable, short *theCode)
- {
- short i, x, y;
-
- long destRegisters[5];
- long targetByte;
-
- *(*(short **) &theCode)++ = 0xa9ff;
-
- for (i = 0; i < 5; i++)
- destRegisters[i] = 32768 + i * 65536L;
-
- for (y = 0; y < height; ++y)
- {
- for (x = 0; x < 32; ++x) {
- long registerOffset;
-
- targetByte = *mappingTable++;
-
- #if EMIT_POSTINC
- for (i = 0; i < 5; i++) {
- registerOffset = targetByte - destRegisters[i];
- if (registerOffset >= -32768 && registerOffset < 32768) {
- switch(i) {
- case 0:
- *(*(short **) &theCode)++ = move_b_a5plus_a0;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 1:
- *(*(short **) &theCode)++ = move_b_a5plus_a1;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 2:
- *(*(short **) &theCode)++ = move_b_a5plus_a2;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 3:
- *(*(short **) &theCode)++ = move_b_a5plus_a3;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 4:
- *(*(short **) &theCode)++ = move_b_a5plus_a4;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- default:
- Debugger();
- break;
- }
- break;
- }
- }
- #else
- for (i = 0; i < 0; i++) {
- registerOffset = targetByte - destRegisters[i];
- if (registerOffset >= -32768 && registerOffset < 32768) {
- switch(i) {
- case 0:
- *(*(short **) &theCode)++ = move_b_off_a5_to_a0;
- *(*(short **) &theCode)++ = x;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 1:
- *(*(short **) &theCode)++ = move_b_off_a5_to_a1;
- *(*(short **) &theCode)++ = x;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 2:
- *(*(short **) &theCode)++ = move_b_off_a5_to_a2;
- *(*(short **) &theCode)++ = x;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 3:
- *(*(short **) &theCode)++ = move_b_off_a5_to_a3;
- *(*(short **) &theCode)++ = x;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- case 4:
- *(*(short **) &theCode)++ = move_b_off_a5_to_a4;
- *(*(short **) &theCode)++ = x;
- *(*(short **) &theCode)++ = registerOffset;
- break;
- default:
- Debugger();
- break;
- }
- break;
- }
- }
- // So, we have no register coverage for the destination
- // We'll have to emit some slower code.
- registerOffset = targetByte - 32768;
- *(*(short **) &theCode)++ = immediate_long_load_d0;
- *(*(long **) &theCode)++ = registerOffset;
- *(*(short **) &theCode)++ = move_byte_da5_a0_d0_L;
- *(*(short **) &theCode)++ = x;
- *(*(short **) &theCode)++ = no_constant_for_load;
-
- #endif
- }
- // add rowbytes to the row register
- *(*(short **) &theCode)++ = adda_w_const_a5;
- #if EMIT_POSTINC
- *(*(short **) &theCode)++ = rowBytes - 32;
- #else
- *(*(short **) &theCode)++ = rowBytes;
- #endif
-
- }
- *(*(short **) &theCode)++ = rts;
- }
-
- //
- // Blit the entire bitmap from source to dest, using the same column
- // mappings for each column across
- //
-
- void
- BlitColumns(char *sourceBase, char *destinationBase, short height, short width,
- short rowBytes, long *columnMapping)
- {
- short x, y;
- char *sourceRow, *sourceByte;
- long *offsetHere;
-
- for (x = 0; x < width; x += 32)
- {
- char *destinationRow;
-
- offsetHere = columnMapping;
- sourceRow = sourceBase + x;
- destinationRow = destinationBase + x;
-
- BlitOneColumn(sourceRow, destinationRow, height, rowBytes, offsetHere);
- }
- }
-
- main()
- {
- WindowPtr sourceWindow, destinationWindow;
- Rect sourceRect, destRect;
- Rect frame;
- PicHandle picture;
- GWorldPtr sourceGWorld, destinationGWorld;
- PixMapHandle sourcePix, destinationPix;
- GWorldPtr savedGWorld;
- GDHandle savedGDevice;
- short height, width, rowBytes;
- short i, x, y;
- long *buffer1, *offsetHere;
- char *sourceBase, *destinationBase;
- long *ColumnMaps[kFrameCount];
- short *FrameCode[kFrameCount];
- short wavyTable[32];
-
- InitGraf(&qd.thePort);
- InitWindows();
-
- picture = GetPicture(pictID);
-
- frame = (**picture).picFrame;
- width = frame.right - frame.left;
- height = frame.bottom - frame.top;
- SetRect(&sourceRect, 50, 50, width + 50, height + 50);
- destRect = sourceRect;
- OffsetRect(&destRect, 0, 220);
-
- sourceWindow = NewCWindow(nil,&sourceRect,
- "\pSource", TRUE,
- documentProc, (WindowPtr)(-1), FALSE, 0);
-
- destinationWindow = NewCWindow(nil,&destRect,
- "\pDestination", TRUE,
- documentProc, (WindowPtr)(-1), FALSE, 0);
-
- GetGWorld(&savedGWorld, &savedGDevice);
- NewGWorld(&sourceGWorld,8,&frame,nil,nil,0);
- NewGWorld(&destinationGWorld,8,&frame,nil,nil,0);
- sourcePix = GetGWorldPixMap(sourceGWorld);
- LockPixels(sourcePix);
- SetGWorld(sourceGWorld, nil);
- DrawPicture(picture,&sourceGWorld->portRect);
- UnlockPixels(sourcePix);
- LockPixels(destinationPix);
- SetGWorld(destinationGWorld, nil);
- EraseRect(&destinationGWorld->portRect);
- UnlockPixels(destinationPix);
- SetGWorld(savedGWorld, savedGDevice);
-
- sourcePix = GetGWorldPixMap(sourceGWorld);
- destinationPix = GetGWorldPixMap(destinationGWorld);
- rowBytes = (**GetGWorldPixMap(sourceGWorld)).rowBytes & 0x7FFF;
-
- SetPort(sourceWindow);
- LockPixels(sourcePix);
- CopyBits((BitMap *)*sourcePix, &sourceWindow->portBits,
- &sourceGWorld->portRect, &sourceWindow->portRect, srcCopy, nil);
- UnlockPixels(sourcePix);
-
- SetPort(destinationWindow);
- LockPixels(sourcePix);
- LockPixels(destinationPix);
-
- MakeSineTable(wavyTable);
-
- for (x = 0; x < kFrameCount; x++)
- {
- ColumnMaps[x] = (long *)NewPtr(sizeof(long) * 32 * height);
- if (ColumnMaps[x] == nil)
- Debugger();
-
- FrameCode[x] = (short *) NewPtr(12L * 32 * height // move the rows
- + 6 * 20 * height // the row reloads
- + 500); // el sloppolo
- if (FrameCode[x] == nil)
- Debugger();
-
- GenerateMappingColumn(ColumnMaps[x], width, height, rowBytes, x, wavyTable);
- WriteSomeCode(height, rowBytes, ColumnMaps[x], FrameCode[x]);
-
- // DisposePtr((Ptr)ColumnMaps[x]);
-
- MoveTo(width / 2 - 20, x * 3 + 10); // amuse the user
- LineTo(width / 2 + 20, x * 3 + 10);
- }
-
- SetPort(destinationWindow);
-
- sourceBase = (**sourcePix).baseAddr;
- destinationBase = (**destinationPix).baseAddr;
-
- while (!Button()) {
- short *theCode;
- char *sourceRow;
- char *destinationRow;
-
- long startTime, endTime;
- for (i = 0; i < kFrameCount ; i++) {
- theCode = FrameCode[i];
-
- // BlitColumns(sourceBase, destinationBase, height, width,
- // rowBytes, ColumnMaps[i]);
-
- for (x = 0; x < width; x += 32) {
- sourceRow = sourceBase + x;
- destinationRow = destinationBase + x;
-
- startTime = Microseconds();
- asm {
- movem.l a0-a6, -(sp)
-
- movea.l destinationRow, a0
- adda.l #0x8000, a0
- movea.l a0, a1
- adda.l #0x10000, a1
- movea.l a1, a2
- adda.l #0x10000, a2
- movea.l a2, a3
- adda.l #0x10000, a3
- movea.l a3, a4
- adda.l #0x10000, a4
- movea.l sourceRow, a5
-
- movea.l theCode, a6
- jsr (a6) // whee!
- movem.l (sp)+, a0-a6
- }
- endTime = Microseconds();
- Debugger();
- }
-
- CopyBits((BitMap *)*destinationPix, &destinationWindow->portBits,
- &destinationGWorld->portRect, &destinationWindow->portRect, srcCopy, nil);
- if (Button())
- break;
- }
- }
-
- UnlockPixels(sourcePix);
- UnlockPixels(destinationPix);
- }
-